package net.m510.autosurfer.mhbk;

import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.jsoup.nodes.Document;

import net.m510.autosurfer.core.DocumentChecker;
import net.m510.autosurfer.core.exception.UserProcessException;
import net.m510.autosurfer.core.log.LogUtils;
import net.m510.autosurfer.core.process.SurfProcess;

public class MhbkProcessRetryer {
	private static final Logger log = Logger.getLogger(MhbkProcessRetryer.class.getName());
	public static final int DEFAULT_RETRY_MAX = 3;
	public static final long DEFAULT_INTERVAL = 1000;
	private SurfProcess<Document> process;
	private int retryMax = DEFAULT_RETRY_MAX;
	private DocumentChecker retryChecker;
	private long retryInterval = DEFAULT_INTERVAL;
	
	public MhbkProcessRetryer(SurfProcess<Document> process,DocumentChecker retryChecker) {
		super();
		this.process = process;
		this.retryChecker = retryChecker;
	}

	public Document tryProcess(Document doc) throws IOException,UserProcessException {
		Document out;
		UserProcessException lastOccuredException = new UserProcessException("illegal retry state");
		for (int tries = 1; tries <= retryMax; tries++ ) {
			log.info(String.format("処理を試行します。(%d/%d回目)",tries,retryMax));
			if ( tries > 1 ) {
				try {
					Thread.sleep(retryInterval);
				} catch (InterruptedException e) {
					throw new UserProcessException("interval interrupted", e);
				}
			}
			out = process.process(doc);
			try {
				retryChecker.check(out);
				return out;
			} catch (UserProcessException e) {
				log.info("処理 "+process.getClass().getName()+".processの結果が不正です。");
				LogUtils.logStacktrace(log, Level.INFO, e.getStackTrace());
				lastOccuredException = e;
			}
		}
		log.info("規定の試行回数を超えました");
		throw lastOccuredException;
	}
	
	public SurfProcess<Document> getProcess() {
		return process;
	}
	public void setProcess(SurfProcess<Document> process) {
		this.process = process;
	}
	public int getRetryMax() {
		return retryMax;
	}
	public void setRetryMax(int retryMax) {
		this.retryMax = retryMax;
	}
	public DocumentChecker getRetryChecker() {
		return retryChecker;
	}
	public void setRetryChecker(DocumentChecker retryChecker) {
		this.retryChecker = retryChecker;
	}

	public long getRetryInterval() {
		return retryInterval;
	}

	public void setRetryInterval(long retryInterval) {
		this.retryInterval = retryInterval;
	}

}
